﻿using System;
using System.Configuration;
using System.IO;
using System.Web.Security;
using GiveAQuiz.Web.Helpers;

namespace GiveAQuiz.Web.Messenger
{
  /// <summary>
  /// This class implements the methods defined in the IAccountMessenger 
  /// interface.
  /// </summary>
  public class AccountMessenger : IAccountMessenger
  {
    /// <summary>
    /// Creates a new instance of the AccountMessenger class.
    /// </summary>
    /// <param name="msgSender">The IMessageSender interface used to 
    /// actually send messages out to Users.</param>
    /// <param name="webPathHelper">The IWebPathHelper interface 
    /// which is used to map paths in the web application.</param>
    public AccountMessenger(IMessageSender msgSender, IWebPathHelper webPathHelper)
    {
      MessageSender = msgSender;
      WebPathHelper = webPathHelper;
    }

    public IMessageSender MessageSender
    {
      get;
      private set;
    }

    public IWebPathHelper WebPathHelper
    {
      get;
      private set;
    }

    /// <summary>
    /// Send the password reset message to a given user.
    /// </summary>
    /// <param name="user">The user to which the message will be sent.</param>
    /// <param name="newPassword">The newly created password</param>
    public void SendPasswordResetMessage(MembershipUser user, string newPassword)
    {
      string emailTemplate = GetPasswordResetMessageTemplate();

      string url = CreateLogOnLink();

      // replace the values in the template
      string body = String.Format(emailTemplate, newPassword, url);

      // send out the actual message
      MessageSender.SendMessage(
        ConfigurationManager.AppSettings["SupportEmailFrom"],
        user.Email,
        "Give-A-Quiz.com Password Reset",
        body);
    }

    /// <summary>
    /// Send the registration verification message to a given user.
    /// </summary>
    /// <param name="user">The user to which the message will be sent.</param>
    public void SendRegistrationVerificationMessage(MembershipUser user)
    {
      string emailTemplate = GetRegistrationVerificationMessageTemplate();

      // create the link for confirming this user
      string confirmLink = CreateConfirmationLink(user);

      // replace the values in the template
      string body = String.Format(emailTemplate, user.UserName, user.Email, confirmLink);

      // send out the actual message
      MessageSender.SendMessage(
        ConfigurationManager.AppSettings["SupportEmailFrom"],
        user.Email,
        "Give-A-Quiz.com Account Verification",
        body);
    }

    /// <summary>
    /// Get the password reset message template.
    /// </summary>
    /// <returns>The message template for the password reset
    /// message. </returns>
    protected virtual string GetPasswordResetMessageTemplate()
    {
      // get the registration verification email template
      var fileInfo = new FileInfo(WebPathHelper.MapPhysicalPath("~/App_Data/PasswordReset.txt"));
      string emailTemplate = fileInfo.GetContents();
      return emailTemplate;
    }

    /// <summary>
    /// Get the actual registration verification message template.
    /// </summary>
    /// <returns>The message template for the registration verification
    /// message. </returns>
    protected virtual string GetRegistrationVerificationMessageTemplate()
    {
      // get the registration verification email template
      var fileInfo = new FileInfo(WebPathHelper.MapPhysicalPath("~/App_Data/RegistrationVerification.txt"));
      string emailTemplate = fileInfo.GetContents();
      return emailTemplate;
    }

    /// <summary>
    /// Create the link for logging this user on to the system.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <returns>The logon link (e.g. 
    /// http://localhost/GiveAQuiz/Registration/LogOn?ReturnUrl=/GiveAQuiz/Account/ChangePassword
    /// </returns>
    private string CreateLogOnLink()
    {
      // get the full URL for the logon page
      string logOnUrl = WebPathHelper.CreateFullUrl("~/Account/LogOn");
      
      // get the relative URL for the ChangePassword page
      string returnUrl = WebPathHelper.CreateApplicationUrl("~/Account/ChangePassword");

      string confirmUrl = String.Format("{0}?ReturnUrl={1}", logOnUrl, returnUrl);

      return confirmUrl;
    }

    /// <summary>
    /// Create the link for confirming this user.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <returns>The confirmation link (e.g. 
    /// http://localhost/GiveAQuiz/Registration/Confirm/user?token=AB12345CD03
    /// </returns>
    private string CreateConfirmationLink(MembershipUser user)
    {
      // generate a sha1 hash of the email address to use as a token
      // for the confirmation
      string sha1Email = user.Email.ToSHA1Hash().Replace("-", String.Empty);

      // get the full URL for the confirmation page
      string baseUrl = WebPathHelper.CreateFullUrl("~/Registration/Confirm");

      string confirmUrl =
        String.Format("{0}?UserName={1}&Token={2}", baseUrl, user.UserName, sha1Email);

      return confirmUrl;
    }
  }
}